#include "../thread_safe_arena.h"

#include <iostream>
#include <thread>

void test()
{
  good_cptl::SysThreadSafeArena arena;
  uint32_t *a = (uint32_t*)arena.allocate(sizeof(uint32_t));
  *a = 42;
  std::cout << *a << std::endl;
  std::cout << "--------------------------------" << std::endl;
  uint32_t * array1 = (uint32_t*)arena.allocate(sizeof(uint32_t) * 10000);
  for (int i = 0; i < 10000; ++i) {
    array1[i] = i * 10;
  }
  for (int i = 0; i < 10000; ++i) {
    if (i % 1010 == 0)
    std::cout << array1[i] << std::endl;
  }
  std::cout << "--------------------------------" << std::endl;
  uint32_t * array2 = (uint32_t*)arena.allocate(sizeof(uint32_t) * 128);
  for (int i = 0; i < 128; ++i) {
    array2[i] = i * 10;
  }
  for (int i = 0; i < 128; ++i) {
    if (i % 37 == 0)
    std::cout << array2[i] << std::endl;
  }
  std::cout << "--------------------------------" << std::endl;
  uint32_t * array3 = (uint32_t*)arena.allocate(sizeof(uint32_t) * 256);
  for (int i = 0; i < 256; ++i) {
    array3[i] = i * 10;
  }
  for (int i = 0; i < 256; ++i) {
    if (i % 37 == 0)
    std::cout << array3[i] << std::endl;
  }
  arena.deallocate(array3, sizeof(uint32_t) * 256);
  std::cout << "--------------------------------" << std::endl;
  uint32_t * array4 = (uint32_t*)arena.allocate(sizeof(uint32_t) * 128);
  for (int i = 0; i < 128; ++i) {
    array4[i] = i * 10;
  }
  for (int i = 0; i < 128; ++i) {
    if (i % 37 == 0)
    std::cout << array4[i] << std::endl;
  }
}

void stress_test()
{
  good_cptl::SysThreadSafeArena arena;
  // for (int i = 0; i < 100; ++i) {
  //   uint32_t *a = (uint32_t*)arena.allocate(sizeof(uint32_t));
  //   *a = i;
  // }

  constexpr int kThreads = 8;
  std::vector<std::thread> workers;
  for (int i = 0; i < kThreads; ++i) {
    workers.emplace_back([&, i]() {
      for (int j = 0; j < 100; ++j) {
        uint32_t *a = (uint32_t*)arena.allocate(sizeof(uint32_t));
        *a = i * 1000000 + j;

        void* medium = arena.allocate(1024);
        void* large = arena.allocate(8192);
      }
    });
  }
  for (int i = 0; i < kThreads; i++) {
    workers[i].join();
  }
}



int main()
{
  stress_test();
  return 0;
}